import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/store/user'
import api from '@/common/api'
import i18n from '@/i18n'
import storage from '@/common/storage'
import moment from 'moment'

/*
    Vuex - 状态管理模式
    管理应用中所有组件的状态，并以相应的规则保证状态以一种可预测的方式发生变化。
    对前端进行统一的状态管理，解决不同组件共享数据的问题。
    不同视图需要变更同一状态的问题，使用vuex之后，状态变化更加清晰。
*/
Vue.use(Vuex)

/*
   state = rootState 存放全局初始化变量
   是一个单一状态树，作为Vuex的数据源。
 */
const rootState = {
    //页面当前状态：登录、注册、重置密码...
    modalStatus: {
        mode: 'Login', // or 'register'
        //是否可见
        visible: false
    },
    //网站基本配置信息
    websiteConfig: {
        recordName: '© 2022',
        projectName: 'SOJ',
        shortName: 'OJ',
        recordUrl: '#',
        projectUrl: '#',
        openPublicDiscussion: true
    },
    //可重新注册的倒计时
    registerTimeOut: 60,
    //可重新重置的倒计时
    resetTimeOut: 90,
    //网站语言
    language: storage.get('Web_Language') || 'zh-CN',
}

/*
    getter = rootGetters 对象状态加工函数
    通过函数对state中的数据进行加工（派生）
 */
const rootGetters = {
    'modalStatus'(state) {
        return state.modalStatus
    },
    'registerTimeOut'(state) {
        return state.registerTimeOut
    },
    'resetTimeOut'(state) {
        return state.resetTimeOut
    },
    'websiteConfig'(state) {
        return state.websiteConfig
    },
    'webLanguage'(state) {
        return state.language
    }
}

/*
    mutation = rootMutations 修改state的状态
    state状态发生变化时都由mutation进行修改，方便追踪数据
 */
const rootMutations = {
    /**
     * 修改页面当前状态
     * @param state 页面状态
     * @param mode 页面模式：登录、注册、重置密码等等
     * @param visible 是否可见
     */
    changeModalStatus(state, {mode, visible}) {
        if (mode !== undefined) {
            state.modalStatus.mode = mode
        }
        if (visible !== undefined) {
            state.modalStatus.visible = visible
        }
    },

    /**
     * 修改注册倒计时
     * @param state 注册倒计时状态
     * @param time 倒计时
     */
    changeRegisterTimeOut(state, {time}) {
        if (time !== undefined) {
            state.registerTimeOut = time
        }
    },

    /**
     * 修改重置倒计时
     * @param state 重置倒计时状态
     * @param time 倒计时
     */
    changeResetTimeOut(state, {time}) {
        if (time !== undefined) {
            state.resetTimeOut = time
        }
    },
    /**
     * 注册邮件和重置邮件倒计时
     * @param state 倒计时状态
     * @param name 倒计时类型
     */
    startTimeOut(state, {name}) {
        //倒计时结束时重置秒数
        if (state.resetTimeOut == 0) {
            state.resetTimeOut = 90
            return;
        }
        if (state.registerTimeOut == 0) {
            state.registerTimeOut = 60
            return;
        }
        //倒计时自减
        if (name == 'resetTimeOut') {
            state.resetTimeOut--;
        }
        if (name == 'registerTimeOut') {
            state.registerTimeOut--;
        }
        //设置定时器，1秒执行一次
        setTimeout(() => {
            this.commit('startTimeOut', {name: name})
        }, 1000);
    },
    /**
     * 修改网页基本配置
     * @param state 网站配置状态
     * @param payload 修改的信息
     */
    changeWebsiteConfig(state, payload) {
        state.websiteConfig = payload.websiteConfig
    },
    /**
     * 修改网页语言
     * @param state 网页语言状态
     * @param language zh or en
     */
    changeWebLanguage(state, {language}) {
        if (language) {
            state.language = language
            i18n.locale = language
            moment.locale(language);
        }
        storage.set('Web_Language', language)
    }
}

/*
    action = rootActions 执行异步操作
    类似mutation，但是包含异步操作，执行修改操作时需要触发mutation
 */
const rootActions = {
    changeModalStatus({commit}, payload) {
        commit('changeModalStatus', payload)
    },
    changeResetTimeOut({commit}, payload) {
        commit('changeResetTimeOut', payload)
    },
    changeRegisterTimeOut({commit}, payload) {
        commit('changeRegisterTimeOut', payload)
    },
    startTimeOut({commit}, payload) {
        commit('startTimeOut', payload)
    },
    /**
     * 修改 Dom标题
     * @param commit
     * @param state
     * @param payload 修改的数据
     */
    changeDomTitle({commit, state}, payload) {
        let ojName = state.websiteConfig.shortName ? state.websiteConfig.shortName : 'OJ'
        if (payload && payload.title) {
            window.document.title = payload.title + ' - ' + ojName
        } else {
            window.document.title = state.route.meta.title + ' - ' + ojName
        }
    },
    /**
     * 获取网站基本配置信息
     * @param commit
     */
    getWebsiteConfig({commit}) {
        api.getWebsiteConfig().then(res => {
            commit('changeWebsiteConfig', {
                websiteConfig: res.data.data
            })
        })
    },
}

export default new Vuex.Store({
    modules: {
        user
    },
    state: rootState,
    getters: rootGetters,
    mutations: rootMutations,
    actions: rootActions,
})
